package org.subatu.orm.query.condition;


import org.subatu.orm.query.base.BaseSql;
import org.subatu.orm.query.base.JoinEnum;
import org.subatu.orm.query.table.CondColumn;
import org.subatu.orm.query.table.TableDef;
import org.subatu.orm.util.ChkUtil;
import org.subatu.orm.util.SqlUtil;

import java.util.List;

/**
 * 查询
 */
public interface Join<T extends On> extends BaseSql {

    // 连表 sql
    // StringBuilder sqlData().joinSql = new StringBuilder();

    default T leftJoin(Class<?> table, String alias) {
        return join(JoinEnum.LEFT_JOIN, table, alias);
    }

    default T rightJoin(Class<?> table, String alias) {
        return join(JoinEnum.RIGHT_JOIN, table, alias);
    }

    default T innerJoin(Class<?> table, String alias) {
        return join(JoinEnum.INNER_JOIN, table, alias);
    }

    default T join(Class<?> table, String alias) {
        return (T) join(JoinEnum.JOIN, table, alias);
    }

    default T join(JoinEnum joinEnum, Class<?> table, String alias) {

        // 子类的构造函数,默认包含了 tableName,所以不需要设置
        String tableName = SqlUtil.getTableName(table);
        TableDef tableDef = new TableDef(tableName);
        tableDef.setJoinEnum(joinEnum);
        tableDef.setAlias(alias);
        sqlData().joinList.add(tableDef);
        // map中也设置一份
        this.sqlData().tableAliasMap.put(tableDef.getTableName(), alias);

        return (T) this;
    }

    default T joinSql(String sql) {
        sqlData().joinSql.append(sql);
        return (T) this;
    }

    default String buildJoinSql() {
        if (sqlData().joinSql.length() > 0 || ChkUtil.isNull(sqlData().joinList)) {
            // 如果手工设置了 sql, 直接返回
            return sqlData().joinSql.toString();
        }
        sqlData().joinSql.setLength(0);

        for (TableDef tableDef : sqlData().joinList) {
            sqlData().joinSql.append(" " + tableDef.getJoinEnum().getValue() + " " + tableDef.getTableName());
            if (ChkUtil.isNotNull(tableDef.getAlias())) {
                sqlData().joinSql.append(" as " + tableDef.getAlias() + " ");
            }

            List<CondColumn> conditionList = tableDef.getJoinConditionList();
            if (conditionList.size() == 0) continue;

            sqlData().joinSql.append(" on ");
            String allCondSql = getAllCondSql(conditionList);
            sqlData().joinSql.append(allCondSql);

        }

        return sqlData().joinSql.toString();
    }
}
